package com.blah.gwtgames.client.sudoku;

import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FocusListener;
import com.google.gwt.user.client.ui.FocusPanel;
import com.google.gwt.user.client.ui.HasFocus;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.KeyboardListener;
import com.google.gwt.user.client.ui.Panel;
import com.google.gwt.user.client.ui.SourcesClickEvents;
import com.google.gwt.user.client.ui.SourcesKeyboardEvents;
import com.google.gwt.user.client.ui.Widget;

public class Cell extends Composite implements SourcesClickEvents,
		SourcesKeyboardEvents, HasFocus
{
	private int value;
	private boolean locked;
	private Panel panel;
	private int conflictCount = 0;
	private int highlightCount = 0;

	private Image symbol = new Image();

	HasFocus focus = null;

	public Cell()
	{
		initUI(0, false);
	}

	public Cell(int value, boolean locked)
	{
		initUI(value, locked);
	}

	public Cell(CellValue cellValue)
	{
		initUI(cellValue.value, cellValue.locked);
	}
	
	private void initUI(int value, boolean locked)
	{
		final FocusPanel focusPanel = new FocusPanel();
		this.panel = focusPanel;
		panel.add(symbol);
		focus = focusPanel;

		setValue(value);
		setLocked(locked);
		
		focus.addFocusListener(new FocusListener()
		{ 
			public void onFocus(Widget sender)
			{
				focusPanel.addStyleName("focused");
			}

			public void onLostFocus(Widget sender)
			{
				focusPanel.removeStyleName("focused");
			}
			
		});
		
		initWidget(panel);
	}

	public void setLocked(boolean locked)
	{
		this.locked = locked;
		if (locked)
			panel.addStyleName("locked");
		else
			panel.removeStyleName("locked");
	}
	
	public boolean isLocked()
	{
		return locked;
	}

	public int getValue()
	{
		return value;
	}

	public void setValue(int value)
	{
		this.value = value;
		symbol.setUrl("images/sudoku/" + value + ".png");
	}
	
	public void clearConflicts()
	{
		if (conflictCount > 0)
		{
			conflictCount = 0;
			removeStyleName("conflict");
		}
	}

	public void setConflicted(boolean conflicted)
	{
		if (conflicted && ++conflictCount == 1)
		{
			panel.addStyleName("conflict");
		}
		
		if (!conflicted && --conflictCount == 0)
		{
			panel.removeStyleName("conflict");
		}
	}
	
	public boolean isConflicted()
	{
		return conflictCount > 0;
	}
	
	public void setHighlighted(boolean highlighted)
	{
		if (highlighted && ++highlightCount == 1)
		{
			panel.addStyleName("highlight");
		}
		
		if (!highlighted && --highlightCount == 0)
		{
			panel.removeStyleName("highlight");
		}
	}
	
	public boolean isHighlighted()
	{
		return highlightCount > 0;
	}

	public void addClickListener(ClickListener listener)
	{
		symbol.addClickListener(listener);
	}

	public void removeClickListener(ClickListener listener)
	{
		symbol.addClickListener(listener);
	}

	public void addKeyboardListener(KeyboardListener listener)
	{
		focus.addKeyboardListener(listener);
	}

	public void removeKeyboardListener(KeyboardListener listener)
	{
		focus.removeKeyboardListener(listener);
	}

	public int getTabIndex()
	{
		return focus.getTabIndex();
	}

	public void setAccessKey(char key)
	{
		focus.setAccessKey(key);
	}

	public void setFocus(boolean focused)
	{
		focus.setFocus(focused);
	}

	public void setTabIndex(int index)
	{
		focus.setTabIndex(index);
	}

	public void addFocusListener(FocusListener listener)
	{
		focus.addFocusListener(listener);
	}

	public void removeFocusListener(FocusListener listener)
	{
		focus.removeFocusListener(listener);
	}
}
